package level.editor.control.object;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;

import javax.swing.Icon;
import javax.swing.SwingUtilities;

import level.editor.control.Handler;
import level.editor.control.main.Main;
import level.editor.control.object.ObjectControl.ObjectSelect;
import level.editor.control.tile.TileConstants;
import level.model.GameObject;

public class ObjectHandler extends Handler implements ActionListener,
		WindowFocusListener
{
	public ObjectHandler(ObjectControl control)
	{
		super();
		this.control = control;

		control.addKeyListener(this);
		
		selectedObject = null;
		icon = null;
//		selectedObject = GameObjectFactory.createGoomba(0, 0);
//		icon = new ImageIcon(selectedObject.getIconPath());
	}

	@Override
	public void finish()
	{
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent e)
	{
		if (SwingUtilities.isLeftMouseButton(e) && e.getSource() instanceof Main && selectedObject != null)
		{
			Main main = (Main) e.getSource();
			ObjectLayer layer = main.getObjectLayer();
			main.requestFocusInWindow();
			Point pt = noSnapPoint(main.getOrigin(), e.getPoint());
			GameObject toAdd = selectedObject.cloneObject();
			toAdd.setX(pt.x);
			toAdd.setY(pt.y);
			layer.addObject(toAdd);
			main.setDirty(Main.DIRTY);
			main.createMemento();
			layer.repaint();
		}
	}

	@Override
	public void mouseDragged(MouseEvent e)
	{

	}

	@Override
	public void mouseReleased(MouseEvent e)
	{

	}

	// Implement ghost circles here

	@Override
	public void mouseMoved(MouseEvent e)
	{
		if (e.getSource() instanceof Main && selectedObject != null)
		{
			Main main = (Main) e.getSource();
			main.requestFocusInWindow();
			if (main.getObjectLayer() != null
					&& !main.getObjectLayer().isLocked()
					&& main.getObjectLayer().isVisible())
			{
				if (buffer == null)
				{
					ObjectLayer layer = main.getObjectLayer();
					Point point = noSnapPoint(main.getOrigin(), e.getPoint());
					
					selectedObject.setX(point.x - selectedObject.getW() / 2);
					selectedObject.setY(point.y - selectedObject.getH() / 2);
					
					layer.setGhost(selectedObject, icon);
					layer.repaint();
				}
			}
		}
	}

	@Override
	public void keyPressed(KeyEvent e)
	{

	}

	@Override
	public void keyReleased(KeyEvent e)
	{

	}

	@Override
	public void windowGainedFocus(WindowEvent arg0)
	{
		// TODO Auto-generated method stub

	}

	@Override
	public void windowLostFocus(WindowEvent arg0)
	{

	}

	@Override
	public void paint(Graphics2D g, Point topLeft)
	{

	}

	@Override
	public void actionPerformed(ActionEvent e)
	{
		if (e.getSource() instanceof ObjectSelect)
		{
			ObjectSelect s = (ObjectSelect) e.getSource();
			selectedObject = s.getObject();
			icon = s.getGameIcon();
			
			control.registerHandler();
			control.requestFocusInWindow();
			control.getMain().repaint();
		}
	}

	@SuppressWarnings("unused")
	private Point snapPoint(Point origin, Point initialPoint)
	{
		Point point = new Point();

		initialPoint.x += TileConstants.TILE_SIZE / 2;
		initialPoint.y += TileConstants.TILE_SIZE / 2;
		point.x = (int) (initialPoint.getX() - origin.getX());
		point.y = (int) (initialPoint.getY() - origin.getY());

		point.x = point.x - (point.x < 0 ? TileConstants.TILE_SIZE : 0);
		point.y = point.y - (point.y < 0 ? TileConstants.TILE_SIZE : 0);

		point.x = point.x - point.x % TileConstants.TILE_SIZE;
		point.y = point.y - point.y % TileConstants.TILE_SIZE;

		return point;
	}

	@SuppressWarnings("unused")
	private Point regularSnapPoint(Point origin, Point initialPoint)
	{
		Point point = new Point();
		point.x = (int) (initialPoint.getX() - origin.getX());
		point.y = (int) (initialPoint.getY() - origin.getY());

		point.x = point.x - (point.x < 0 ? TileConstants.TILE_SIZE : 0);
		point.y = point.y - (point.y < 0 ? TileConstants.TILE_SIZE : 0);

		point.x = point.x - point.x % TileConstants.TILE_SIZE;
		point.y = point.y - point.y % TileConstants.TILE_SIZE;

		return point;
	}

	private Point noSnapPoint(Point origin, Point initialPoint)
	{
		Point point = new Point();

		point.x = (int) (initialPoint.getX() - origin.getX());
		point.y = (int) (initialPoint.getY() - origin.getY());

		return point;
	}

	@SuppressWarnings("unused")
	private ObjectBuffer newObjectBuffer(Integer layerNumber, Point point,
			Main main, boolean isRect)
	{
		ObjectBuffer buffer = new ObjectBuffer(layerNumber, main);
		return buffer;
	}

	private ObjectControl control;
	private ObjectBuffer buffer;
	private GameObject selectedObject;
	private Icon icon;
}
